import * as THREE from 'three'
import { Mesh, MeshNormalMaterial } from 'three'
import createApp from '../../core'

function createRingGeometry (dom: HTMLElement) {
  const { camera, scene, update, gui } = createApp(dom)
  camera.position.set(0, 0, 100)
  camera.lookAt(scene.position)

  const mesh = createRingFromGeometry()
  mesh.position.x = -40
  scene.add(mesh)

  const bufferMesh = createRingFromBufferGeometry()
  bufferMesh.position.x = 40
  scene.add(bufferMesh)

  update((time: number) => {
    const angle = time / 1000
    mesh.rotation.set(angle, angle, 0)

    bufferMesh.rotation.set(angle, angle, 0)
  })

  function updateMeshs () {
    generateGeometry(mesh)
    generateGeometry(bufferMesh)
  }

  gui.add(data, 'innerRadius', 0, 50).onChange(updateMeshs)
  gui.add(data, 'outerRadius', 0, 50).onChange(updateMeshs)
  gui.add(data, 'thetaSegments', 3, 30, 1).onChange(updateMeshs)
  gui.add(data, 'phiSegments', 1, 30, 1).onChange(updateMeshs)
  gui.add(data, 'thetaStart', 0, Math.PI * 2).onChange(updateMeshs)
  gui.add(data, 'thetaLength', 0, Math.PI * 2).onChange(updateMeshs)
}

const data = {
  innerRadius: 15,
  outerRadius: 20,
  thetaSegments: 10,
  phiSegments: 10,
  thetaStart: 0,
  thetaLength: Math.PI * 2
}

function createRingFromGeometry () {
  const { innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength } = data
  const geometry = new THREE.RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength)
  const material = new MeshNormalMaterial({ wireframe: true })
  const mesh = new Mesh(geometry, material)
  return mesh
}

function createRingFromBufferGeometry () {
  const { innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength } = data
  const geometry = new THREE.RingBufferGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength)
  const material = new MeshNormalMaterial({ side: THREE.DoubleSide })
  const mesh = new Mesh(geometry, material)
  return mesh
}

function generateGeometry (mesh: THREE.Mesh) {
  const { innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength } = data
  const geometry = new THREE.RingBufferGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength)
  mesh.geometry.dispose()
  mesh.geometry = geometry
}

export {
  createRingGeometry
}
